/**
 *
 * Http Request tools
 *
 * Should be used to process GET/POST/PUT/DELETE requests from within endi vue js code
 *
 * Manage
 *
 *    custom headers
 *    csrf token
 *    FormData
 *    Translate Login Errors, Forbidden Errors
 *
 * import {http} from '@/helpers/http';
 *
 * http.get(url, [data], [options]);
 * http.post(url, data, [options]);
 * http.put(url, data, [options]);
 * http.delete(url, [data], [options]);
 *
 * @param {String} url
 * @param {Object|FormData} data
 * @param {Object} options
 */

import { getCsrfToken } from './context'

function addCsrfToken(url: string, headers: Object, body: Object | FormData) {
  const token = getCsrfToken()
  if (!token) {
    return
  }
  headers['X-CSRF-Token'] = token
  if (body instanceof FormData) {
    body.append('csrf_token', token)
  } else {
    body['csrf_token'] = token
  }
}

function request(method: string) {
  return (
    url: string,
    body: Object | FormData,
    options: Object,
    allow_prefetch_request: Boolean = true
  ): Promise<any> => {
    let headersOptions = { }
    if(allow_prefetch_request) {
      headersOptions = {'X-Requested-With': 'XMLHttpRequest'}
    }
    const requestOptions = {
      method,
      headers: headersOptions,
      ...options,
    }
    if (body) {
      addCsrfToken(url, requestOptions.headers, body)
      if (body instanceof FormData) {
        // requestOptions.headers['Content-Type'] = 'multipart/form-data'
        requestOptions.body = body
      } else {
        requestOptions.headers['Content-Type'] = 'application/json'
        requestOptions.body = JSON.stringify(body)
      }
    }
    return fetch(url, requestOptions).then(handleResponse, handleResponse)
  }
}

async function handleResponse(response): Promise<any> {
  const contentType = response.headers?.get('content-type');
  const isJson = contentType?.includes('application/json') || contentType?.includes('application/geo+json');
  const data = isJson ? await response.json() : null;

  // check for error response
  if (!response.ok) {
    // get error message from body or default to response status
    console.log(response)
    let error = (data && data.errors) || response.status
    if (response.status == 401) {
      error = "Cette page n'existe pas"
    } else if (response.status == 403) {
      error = "Vous n'êtes plus authentifié"
    } else if (response.status == 415) {
      error = "Ce fichier ne peut pas être signé numériquement car son format n'est pas correct. Vous pouvez essayer de l'imprimer dans un nouveau fichier PDF avant de le recharger."
    }
    return Promise.reject(error)
  }
  return data
}

export function buildUrl(path: string, data: Object | Array<Array<string, string>>): string {
  const params = new URLSearchParams(data)
  return `${path}?${params}`
}

const http = {
  get: request('GET'),
  post: request('POST'),
  put: request('PUT'),
  patch: request('PATCH'),
  delete: request('DELETE'),
}
export default http
